/*
 * Copyright (c) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "hi_ext_util.h"
#include "http_util.h"

/**
    文件名、content-type 对.
*/
typedef struct ExtCttPair {
    const char* ext; // 文件扩展名
    const char* ctt; // content-type
}   ExtCttPair;

/**
    ExtCttPair table.
*/
static const ExtCttPair G_EXT_CTT_TAB[] = {
    { "html",   "text/html" },
    { "htm",    "text/html" },
    { "xml",    "text/xml" },
    { "css",    "text/css" },
    { "js",     "text/javascript" },
    { "txt",    "text/plain" },
    { "text",   "text/plain" },

    { "json",   "application/json" },

    { "jpg",    "image/jpeg" },
    { "gif",    "image/gif" },
    { "png",    "image/png" },
    { "ico",    "image/x-ico" },
    { "mp4",    "video/mpeg4" },
};

/**
    通过文件名后缀返回content-type.
*/
const char* FileExtToCtt(const char* filePath)
{
    HI_ASSERT(filePath);
    const char *ext = NULL;
    int i;

    ext = strrchr(filePath, '.');
    if (!ext) {
        return NULL;
    }
    ext++;

    for (i = 0; i < HI_ARRAY_SIZE(G_EXT_CTT_TAB); i++) {
        if (HiStricmp(G_EXT_CTT_TAB[i].ext, ext) == 0) {
            return G_EXT_CTT_TAB[i].ctt;
        }
    }
    return NULL;
}

/**
    errno to http2 error code.
*/
uint32_t ErrnoToH2Code(int err)
{
    if (err == 0) {
        return 0; // no error
    } else if (err == -ECANCELED) {
        return 0x08; // CANCEL
    } else {
        return 0x02; // innernal error
    }
}

/**
    stream type name table.
*/
static const char* g_h2StrmTypeTab[] = {
    "DATA",
    "HEADERS",
    "PRIORITY",
    "RST_STREAM",
    "SETTINGS",
    "PUSH_PROMISE",
    "PING",
    "GOAWAY",
    "WINDOW_UPDATE"
    "CONTINUATION",
};

/**
    获取stream type的名称.
*/
const char* H2StrmTypeStr(uint8_t type)
{
    if (type >= HI_ARRAY_SIZE(g_h2StrmTypeTab)) {
        return "?";
    } else {
        return g_h2StrmTypeTab[type];
    }
}

/**
    http method string to code.
*/
uint32_t HttpMethodToCode(const char* method)
{
    if (HiStricmp(method, "GET") == 0) {
        return HMC_GET;
    } else if (HiStricmp(method, "HEAD") == 0) {
        return HMC_HEAD;
    } else if (HiStricmp(method, "PUT") == 0) {
        return HMC_PUT;
    } else if (HiStricmp(method, "POST") == 0) {
        return HMC_POST;
    } else {
        LOGE("unkn HTTP method '%s'\n", method);
        return 0;
    }
}

/**
    http method list string to codes.
*/
uint32_t HttpMethodsToCodes(const char* methods)
{
    uint32_t codes = 0;

    if (HiStristr(methods, "GET")) {
        codes |= HMC_GET;
    }
    if (HiStristr(methods, "HEAD")) {
        codes |= HMC_HEAD;
    }
    if (HiStristr(methods, "PUT")) {
        codes |= HMC_PUT;
    }
    if (HiStristr(methods, "POST")) {
        codes |= HMC_POST;
    }
    return codes;
}

/**
    http method code to string.
*/
const char* HttpCodeToMethod(uint32_t mcode)
{
    if (mcode == HMC_GET) {
        return "GET";
    } else if (mcode == HMC_HEAD) {
        return "HEAD";
    } else if (mcode == HMC_PUT) {
        return "PUT";
    } else if (mcode == HMC_POST) {
        return "POST";
    } else {
        LOGE("unkn HTTP method '%#x'\n", mcode);
        return "?";
    }
}

